From ea00661dd8986b9a1380c9c500122dec8ca5a0db Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Sun, 29 Oct 2017 13:52:26 +0100 Subject: [PATCH] CIE: Add conversion from "RGBA float" to "CIE Lab float" Conversions from "RaGaBaA float" to "CIE Lab float", as seen when using gegl:shadows-highlights" go via: "RaGaBaA float" to "RGBA float" "RGBA float" to "RGB float" "RGB float" to "CIE Lab float" A direct conversion from "RaGaBaA float" to "CIE Lab float" in simple C is hindered by the need to check every pixel's alpha value to avoid dividing by zero. The pipeline stalls make it lose out to the look-up table and SIMD based conversions to unassociated alpha. However, we can trivially cut out the second step and still reduce some memory traffic. https://bugzilla.gnome.org/show_bug.cgi?id=789695 --- extensions/CIE.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/extensions/CIE.c b/extensions/CIE.c index d16d862..a010f0b 100644 --- a/extensions/CIE.c +++ b/extensions/CIE.c @@ -646,6 +646,40 @@ rgbf_to_Labf (const Babl *conversion,float *src, } } +static void +rgbaf_to_Labf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + float r = src[0]; + float g = src[1]; + float b = src[2]; + + float xr = 0.43603516f / D50_WHITE_REF_X * r + 0.38511658f / D50_WHITE_REF_X * g + 0.14305115f / D50_WHITE_REF_X * b; + float yr = 0.22248840f / D50_WHITE_REF_Y * r + 0.71690369f / D50_WHITE_REF_Y * g + 0.06060791f / D50_WHITE_REF_Y * b; + float zr = 0.01391602f / D50_WHITE_REF_Z * r + 0.09706116f / D50_WHITE_REF_Z * g + 0.71392822f / D50_WHITE_REF_Z * b; + + float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f; + float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f; + float fz = zr > LAB_EPSILON ? _cbrtf (zr) : (LAB_KAPPA * zr + 16.0f) / 116.0f; + + float L = 116.0f * fy - 16.0f; + float A = 500.0f * (fx - fy); + float B = 200.0f * (fy - fz); + + dst[0] = L; + dst[1] = A; + dst[2] = B; + + src += 4; + dst += 3; + } +} + static void rgbaf_to_Labaf (const Babl *conversion,float *src, float *dst, @@ -903,6 +937,12 @@ conversions (void) "linear", Labf_to_rgbf, NULL ); + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("CIE Lab float"), + "linear", rgbaf_to_Labf, + NULL + ); babl_conversion_new ( babl_format ("RGBA float"), babl_format ("CIE Lab alpha float"), -- 2.30.2